/*
 * @(#)MaintWorkflowMonitoringAction.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.workflow.web;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.Utility;
import com.dcivision.framework.web.AbstractActionForm;
import com.dcivision.framework.web.AbstractMaintAction;
import com.dcivision.workflow.bean.MtmWfStageWfStep;
import com.dcivision.workflow.bean.WorkflowGroup;
import com.dcivision.workflow.bean.WorkflowRecord;
import com.dcivision.workflow.bean.WorkflowStage;
import com.dcivision.workflow.core.SystemWorkflowConstant;
import com.dcivision.workflow.dao.MtmWfStageWfStepDAObject;
import com.dcivision.workflow.dao.WorkflowGroupDAObject;
import com.dcivision.workflow.dao.WorkflowRecordDAObject;
import com.dcivision.workflow.dao.WorkflowStageDAObject;
import com.dcivision.workflow.dao.WorkflowStepDAObject;


/**
  MaintWorkflowMonitoringAction.java

  This class is for maint workflow tracking .

  @author          Angus Shiu
  @company         DCIVision Limited
  @creation date   29/07/2003
  @version         $Revision: 1.19 $
*/
public class MaintWorkflowStageAction extends AbstractMaintAction {

  public static final String REVISION = "$Revision: 1.19 $";
  protected final static String MESSAGE_RECORD_DUPLICATION_STAGE_NAME = "workflow.message.record_duplication_stage_name";

  /** Creates a new instance of MaintWorkflowMonitoringAction */
  public MaintWorkflowStageAction() {
    super();
  }

  /** getFunctionCode
   *
   * Abstract function which sub-class should implement to return the corresponding
   * function code.
   *
   * @return   The function code
   */
  public String getFunctionCode() {
    return(SystemFunctionConstant.WORKFLOW_RECORD);
  }
  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException {
    
    MaintWorkflowStageForm workflowStageForm = (MaintWorkflowStageForm)form;
    AbstractActionForm maintForm = (AbstractActionForm)form;
    
    //modify by nancy
    String navMode = request.getParameter("opMode");
    String workflowRecordID = request.getParameter("workflowRecordID");
    String workflowStageID=(!Utility.isEmpty(request.getParameter("workflowStageID")))?request.getParameter("workflowStageID"):(!Utility.isEmpty(workflowStageForm.getID())?workflowStageForm.getID():"");
    if (Utility.isEmpty(workflowStageForm.getWorkflowGroupID())) {
      workflowStageForm.setWorkflowGroupID(request.getParameter("workflowGroupID"));
    }
    
    //Set the function code for current action.
    ActionForward forward = this.retrieveFunctionCode(request, response, mapping);  
    if (forward!=null) {
      return forward;
    }
    
    //simon_add_start
    Connection conn = this.getConnection(request);
    SessionContainer sessionContainer = (SessionContainer) request.getSession().getAttribute(GlobalConstant.SESSION_CONTAINER_KEY);
    String wfRecordID=workflowStageForm.getWorkflowRecordID();
    WorkflowRecordDAObject WorkflowRecordDAObject = new WorkflowRecordDAObject(this.getSessionContainer(request), this.getConnection(request));
    WorkflowRecord currentRecord = (WorkflowRecord) WorkflowRecordDAObject.getObjectByID(new Integer(wfRecordID));
    WorkflowGroupDAObject wfGroupDAO = new WorkflowGroupDAObject(sessionContainer, conn);
    WorkflowGroup wfGroup = (WorkflowGroup) wfGroupDAO.getObjectByID(currentRecord.getWorkflowGroupID());
    request.setAttribute("workflowGroup", wfGroup);
    //simon_add_end
    WorkflowStageDAObject workflowStageDAO = new WorkflowStageDAObject(this.getSessionContainer(request), this.getConnection(request));
    if (!GlobalConstant.OP_MODE_INSERT_NEW.equals(workflowStageForm.getOpMode())) {
      List workflowStepList = null;

      if(GlobalConstant.OP_MODE_UPDATE_NEW.equals(workflowStageForm.getOpMode())){
        String opMode = (maintForm!=null) ? maintForm.getOpMode() : request.getParameter("opMode");
        //ActionForward forward = this.retrieveFunctionCode(request, response, mapping);
        try{
          this.updateRecord(mapping, maintForm, request, response);
          workflowStepList=(workflowStageDAO.getWorkflowStepListByWorkflowRecordID(new Integer(workflowRecordID)));
          log.debug("the workflowStepList.size()=" + workflowStepList.size());
          this.handleWorkflowRoutine(mapping, maintForm, request, response, opMode, navMode);
          this.commit(request);
          form.reset(mapping, request);
          this.init(mapping, maintForm, request, response);
          addMessage(request, MESSAGE_RECORD_UPDATE);
          request.setAttribute("workflowStepList", workflowStepList);
        } catch (ApplicationException appEx) {
          this.rollback(request);
          handleApplicationException(request, appEx);
        }
        if (isError(request)) {
          maintForm.setNavMode(GlobalConstant.NAV_MODE_EDIT);
          return mapping.findForward(GlobalConstant.NAV_MODE_EDIT);
        } else {
          maintForm.setNavMode(GlobalConstant.NAV_MODE_NEW);
          return mapping.findForward(GlobalConstant.NAV_MODE_NEW);
        }
        }else if(Utility.isEmpty(workflowStageID) && !GlobalConstant.OP_MODE_UPDATE.equals(navMode)) {
          workflowStepList = workflowStageDAO.getWorkflowStepListByWorkflowRecordID(new Integer(workflowRecordID));
        }else{
          workflowStepList = workflowStageDAO.getWorkflowStepListByWorkflowRecordIDAndStageID(new Integer(workflowRecordID),new Integer(workflowStageID));
          //workflowStepList.addAll(workflowStageDAO.getWorkflowStepListByWorkflowRecordID(new Integer(workflowRecordID)));
        }
      //end
      request.setAttribute("workflowStepList", workflowStepList);
    } else {
    	try {
    	  this.insertRecord(mapping, maintForm, request, response);
    	  this.commit(request);
    	  addMessage(request, MESSAGE_RECORD_INSERT);
    	} catch (ApplicationException appEx) {
    		this.rollback(request);
        handleApplicationException(request, appEx);
    	}
    	if (isError(request)) {
        this.canNew(workflowStageForm.getWorkflowGroupID(),workflowStageForm.getWorkflowRecordID(),request);
        maintForm.setNavMode(GlobalConstant.NAV_MODE_NEW);
        return mapping.findForward(GlobalConstant.NAV_MODE_NEW);
      } else {
      	List workflowStepList = (List)request.getAttribute("workflowStepList");
      	if (!Utility.isEmpty(workflowStepList)) {
      		form.reset(mapping, request);
          this.canNew(workflowStageForm.getWorkflowGroupID(),workflowStageForm.getWorkflowRecordID(),request);
          maintForm.setNavMode(GlobalConstant.NAV_MODE_NEW);
          return mapping.findForward(GlobalConstant.NAV_MODE_NEW);
      	} else {
      		WorkflowStepDAObject workflowStepDAO = new WorkflowStepDAObject(this.getSessionContainer(request), this.getConnection(request));
      		String[] relatedStepStr = workflowStageForm.getRelatedStepIDs();
      		List oldStepList = new ArrayList();
      		for(int j=0; j<relatedStepStr.length; j++) {
      			oldStepList.add(workflowStepDAO.getObjectByID(new Integer(relatedStepStr[j])));
      		}
      		request.setAttribute("workflowStepList",oldStepList);
          this.canNew(workflowStageForm.getWorkflowGroupID(),workflowStageForm.getWorkflowRecordID(),request);
      		maintForm.setNavMode(GlobalConstant.NAV_MODE_VIEW);
          return mapping.findForward(GlobalConstant.NAV_MODE_VIEW);
      	}
      }
    }
    if (!Utility.isEmpty(workflowRecordID)) {
      List workflowStepList_status = null;
      workflowStepList_status=workflowStageDAO.getWorkflowStepListByWorkflowRecordID(new Integer(workflowRecordID));
      if(workflowStepList_status==null ||workflowStepList_status.size()==0){
        request.setAttribute(SystemWorkflowConstant.IS_BOOLEAN,SystemWorkflowConstant.FALSE);
      }
    }
    this.canNew(workflowStageForm.getWorkflowGroupID(),workflowStageForm.getWorkflowRecordID(),request);
    return super.execute(mapping, form, request, response);
    
  }
  
  public void insertRecord(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
  	MaintWorkflowStageForm workflowStageForm = (MaintWorkflowStageForm)form;
  	WorkflowStageDAObject workflowStageDAO = new WorkflowStageDAObject(this.getSessionContainer(request), this.getConnection(request));
  	MtmWfStageWfStepDAObject mtmWfStageDAO = new MtmWfStageWfStepDAObject(this.getSessionContainer(request), this.getConnection(request));
  	String[] relatedStepStr = workflowStageForm.getRelatedStepIDs();
  	String[] isPendingStatus = workflowStageForm.getIsNotPending(); 
    if (!this.checkDuplicationStageName(workflowStageForm.getStageName(), new Integer(workflowStageForm.getWorkflowRecordID()), request )) {
  	  WorkflowStage workflowStage = new WorkflowStage();
  	  workflowStage.setStageName(workflowStageForm.getStageName());
  	  workflowStage.setDuration(new Integer(workflowStageForm.getDuration()));
  	  workflowStage.setWorkflowRecordID(new Integer(workflowStageForm.getWorkflowRecordID()));
  	  workflowStage = (WorkflowStage)workflowStageDAO.insertObject(workflowStage);
  	  workflowStageForm.setID(workflowStage.getID().toString());
  	  for (int i = 0; !Utility.isEmpty(relatedStepStr) && i < relatedStepStr.length; i++) {
  		  MtmWfStageWfStep wfStageWfStep = new MtmWfStageWfStep();
  	  	wfStageWfStep.setWorkflowStageID(workflowStage.getID());
  	  	wfStageWfStep.setWorkflowStepID(new Integer(relatedStepStr[i]));
  	  	wfStageWfStep.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
  	  	for (int j = 0 ;!Utility.isEmpty(isPendingStatus) &&  j < isPendingStatus.length; j++) {
  		  	if (relatedStepStr[i].equals(isPendingStatus[j])) {
  		 //	 wfStageWfStep.setRecordStatus(GlobalConstant.RECORD_STATUS_PENDING);   // falcon_delete
  			  wfStageWfStep.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);   // falcon_add
  			  }
  		  }
  		  wfStageWfStep = (MtmWfStageWfStep)mtmWfStageDAO.insertObject(wfStageWfStep);
  	  }
    } else {
      String workflowRecordID = request.getParameter("workflowRecordID");
      List workflowStepList = null;
      workflowStepList = workflowStageDAO.getWorkflowStepListByWorkflowRecordID(new Integer(workflowRecordID));
      request.setAttribute("workflowStepList", workflowStepList);
      throw new ApplicationException(MESSAGE_RECORD_DUPLICATION_STAGE_NAME); 
    }
    if (GlobalConstant.OP_MODE_INSERT_NEW.equals(workflowStageForm.getOpMode())) {
      String workflowRecordID = request.getParameter("workflowRecordID");
      if (!Utility.isEmpty(workflowRecordID)) {
        List workflowStepList = workflowStageDAO.getWorkflowStepListByWorkflowRecordID(new Integer(workflowRecordID));
        request.setAttribute("workflowStepList", workflowStepList);
       // workflowStageForm.setWorkflowRecordID(workflowRecordID);
      }
    }
  }
  
  public void selectRecord(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
  	MaintWorkflowStageForm workflowStageForm = (MaintWorkflowStageForm)form;
  	WorkflowStageDAObject workflowStageDAO = new WorkflowStageDAObject(this.getSessionContainer(request), this.getConnection(request));
  	MtmWfStageWfStepDAObject mtmWfStageDAO = new MtmWfStageWfStepDAObject(this.getSessionContainer(request), this.getConnection(request));
  	String workflowStageID = request.getParameter("workflowStageID");
    List mtmWorkflowStageList = null;
    String[] relatedSteps = null;
    if (!Utility.isEmpty(workflowStageID)) {
  	  mtmWorkflowStageList = mtmWfStageDAO.getListByWorkflowStageID(new Integer(workflowStageID));
    
  	  relatedSteps = new String[mtmWorkflowStageList.size()];
  	  String[] isPendingStatus = new String[mtmWorkflowStageList.size()];
  	  for (int i = 0 ; !Utility.isEmpty(mtmWorkflowStageList) && i < mtmWorkflowStageList.size(); i++) {
  		  MtmWfStageWfStep currentMfStageStep = (MtmWfStageWfStep)mtmWorkflowStageList.get(i);
  		  relatedSteps[i] = currentMfStageStep.getWorkflowStepID().toString();
      /*
  		  if (currentMfStageStep.getRecordStatus().equals(GlobalConstant.RECORD_STATUS_PENDING)) {
  		  	isPendingStatus[i] = currentMfStageStep.getWorkflowStepID().toString();
  		  } else {
  			  isPendingStatus[i] = "-1";
  		  }
        */
  	  }
    }
  	WorkflowStage workflowStage = (WorkflowStage)workflowStageDAO.getObjectByID(new Integer(workflowStageID));
  	workflowStageForm.setFormData(workflowStage);
  	workflowStageForm.setRelatedStepIDs(relatedSteps);
    /*
  	workflowStageForm.setIsNotPending(isPendingStatus);
    */
  }
  
  public void updateRecord(ActionMapping mapping,AbstractActionForm form,HttpServletRequest request,HttpServletResponse response)throws ApplicationException {
  	MaintWorkflowStageForm workflowStageForm = (MaintWorkflowStageForm)form;
  	String[] relatedStepStr = workflowStageForm.getRelatedStepIDs();
  	String[] isPendingStatus = workflowStageForm.getIsNotPending(); 
  	MtmWfStageWfStepDAObject mtmWfStageDAO = new MtmWfStageWfStepDAObject(this.getSessionContainer(request), this.getConnection(request));
  	WorkflowStageDAObject workflowStageDAO = new WorkflowStageDAObject(this.getSessionContainer(request), this.getConnection(request));
  	this.deleteRecord(mapping, form, request, response);
  	if (this.checkDuplicationStageName(workflowStageForm.getStageName(), new Integer(workflowStageForm.getWorkflowRecordID()), request )) {
      WorkflowStage workflowStage = (WorkflowStage)workflowStageDAO.getObjectByID(new Integer(workflowStageForm.getID()));
	  	workflowStage.setStageName(workflowStageForm.getStageName());
	  	workflowStage.setDuration(new Integer(workflowStageForm.getDuration()));
	  	workflowStage = (WorkflowStage)workflowStageDAO.updateObject(workflowStage);

	  	for (int i = 0; !Utility.isEmpty(relatedStepStr) && i < relatedStepStr.length; i++) {
	  		MtmWfStageWfStep wfStageWfStep = new MtmWfStageWfStep();
	  		wfStageWfStep.setWorkflowStageID(workflowStage.getID());
	  		wfStageWfStep.setWorkflowStepID(new Integer(relatedStepStr[i]));
	  		wfStageWfStep.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
	  		for (int j = 0 ; !Utility.isEmpty(isPendingStatus) && j < isPendingStatus.length; j++) {
	  			if (relatedStepStr[i].equals(isPendingStatus[j])) {
	  			//	wfStageWfStep.setRecordStatus(GlobalConstant.RECORD_STATUS_PENDING);   // falcon_delete
	  				wfStageWfStep.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);   // falcon_add
	  			}
	  		}
	  		wfStageWfStep = (MtmWfStageWfStep)mtmWfStageDAO.insertObject(wfStageWfStep);
   
	  	}
    } else {
      throw new ApplicationException(MESSAGE_RECORD_DUPLICATION_STAGE_NAME); 
    }
  }
  
  public void deleteRecord(ActionMapping mapping,
      AbstractActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
throws ApplicationException {
  	MaintWorkflowStageForm workflowStageForm = (MaintWorkflowStageForm)form;
  	MtmWfStageWfStepDAObject mtmWfStageDAO = new MtmWfStageWfStepDAObject(this.getSessionContainer(request), this.getConnection(request));
  	List mtmWfStageList = mtmWfStageDAO.getListByWorkflowStageID(new Integer(workflowStageForm.getID()));
  	for(int i = 0; !Utility.isEmpty(mtmWfStageList) && i < mtmWfStageList.size(); i++) {
  		MtmWfStageWfStep mtmWfStage = (MtmWfStageWfStep)mtmWfStageList.get(i);
  		mtmWfStageDAO.deleteObject(mtmWfStage);
  	}
  	//super.deleteRecord(mapping, form, request, response);
  }

  private boolean checkDuplicationStageName(String stageName, Integer workflowRecordID, HttpServletRequest request)throws ApplicationException{
    WorkflowStageDAObject workflowStageDAO = new WorkflowStageDAObject(this.getSessionContainer(request), this.getConnection(request));
    if (!Utility.isEmpty(workflowStageDAO.getListByStageNameAndWorkflowRecordID(stageName, workflowRecordID))) {
      return true;
    } else {
      return false;
    }
  }
  
  /* (non-Javadoc)
   * @see com.dcivision.framework.web.AbstractAction#getMajorDAOClassName()
   */
  public String getMajorDAOClassName() {
    return("com.dcivision.workflow.dao.WorkflowStageDAObject");
  }
  private void canNew(String workflowGroupID, String workflowRecordID,  HttpServletRequest request)
  throws NumberFormatException, ApplicationException {
    String groupName = null;
    String recordName = null;
    if (!Utility.isEmpty(workflowRecordID)) {
      WorkflowRecordDAObject wfrDAO = new WorkflowRecordDAObject(this
          .getSessionContainer(request), this.getConnection(request));
      recordName = ((WorkflowRecord) wfrDAO.getObjectByID(Integer
          .valueOf(workflowRecordID)))
          .getWorkflowCode();
    }
    if (!Utility.isEmpty(workflowGroupID)) {
      WorkflowGroupDAObject wfgDAO = new WorkflowGroupDAObject(this
          .getSessionContainer(request), this.getConnection(request));
      groupName = ((WorkflowGroup) wfgDAO.getObjectByID(Integer
          .valueOf(workflowGroupID))).getGroupName();
    }
    request.setAttribute("groupName", groupName);
    if (!Utility.isEmpty(workflowRecordID)) {

      request.setAttribute("recordName", recordName);
      MtmWfStageWfStepDAObject mtmStageStepDAO = new MtmWfStageWfStepDAObject(
          this.getSessionContainer(request), this.getConnection(request));
      WorkflowStepDAObject wfStepDAO = new WorkflowStepDAObject(this
          .getSessionContainer(request), this.getConnection(request));
      Integer stepNum = new Integer(wfStepDAO.getListByWorkflowRecordID(
          new Integer(workflowRecordID)).size());
      Integer stageStepNum = new Integer(mtmStageStepDAO
          .getListByWorkflowRecordID(
              new Integer(workflowRecordID)).size());
      if (!stepNum.equals(stageStepNum)) {
        request.setAttribute("canNew", "Y");
      }
    }
  }
}
